<template>
  <div>
    <el-form>
      <el-form-item label="SPU名称">
        <el-input placeholder="请你输入SPU名称" v-model="spuParams.spuName"></el-input>
      </el-form-item>
      <el-form-item label="SPU品牌">
        <el-select placeholder="请选择" v-model="spuParams.tmId">
          <el-option :label="item.tmName" :value="item.id" :key="item.id" v-for="(item,index) in allTradeMarkArr"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input type="textarea" v-model="spuParams.description"></el-input>
      </el-form-item>
      <el-form-item label="SPU图片">
        <el-upload
        v-model:file-list="imgListArr"
          action="/api/admin/product/fileUpload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible" inlin="true">
          <img  :src="dialogImageUrl" alt="Preview Image" style="width=400px; height=400px; margin: 0 auto;  display:block"  />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性">
        <el-select :placeholder="unSelectSaleAttr.length>0?`您还有${unSelectSaleAttr.length}未选择`:`没得选了`" v-model="unSaleAttrIdAndName">
          <el-option :value="`${item.id}:${item.name}`" :label="item.name" v-for="(item,index) in unSelectSaleAttr"></el-option>
        </el-select>
        <el-button
          style="margin-left: 10px"
          type="primary"
          size="default"
          :icon="Plus"
          :disabled="!unSaleAttrIdAndName"
          @click="addSaleAttr"
          >添加销售属性值</el-button>
        <el-table border stripe style="margin: 10px 0px" :data="spuHasSaleAttrArr">
          <el-table-column
            label="序号"
            type="index"
            align="center"
            width="80"
          ></el-table-column>
          <el-table-column label="属性名" width="120" prop="saleAttrName"></el-table-column>
          <el-table-column label="属性值名称列表">
            <template #="{row,$index}">
              <el-tag 
              style="margin: 2px 5px"
              v-for="(item,index) in row.spuSaleAttrValueList"
              :key="item.id"
              class="mx-1"
              closable
              type="success"
              @close="row.spuSaleAttrValueList.splice(index,1)"
            >
              {{item.saleAttrValueName}}
            </el-tag>
             <el-input @blur="toLook(row)" v-model="row.inputValue" v-if="row.flag" placeholder="请输入" size="small" clearable style="width:100px"  ></el-input>
             <el-button v-else type="primary" size="small" :icon="Plus" @click="toEdit(row)"></el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="120"></el-table-column>
        </el-table>

        <el-button type="primary" size="default" @click="save">保存</el-button>
        <el-button size="default" @click="emit('changeScene',0)"
          >取消</el-button
        >
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import {ref, computed} from 'vue'
import { ElMessage } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import type { UploadProps, UploadUserFile } from "element-plus";
//引入请求函数
import {reqAllaTradeMark,reqAllSaleAttr,reqImgList,reqSpuHasSaleAttr,reqAddOrUpdataSpu} from '@/api/product/spu/spu'
import Item from '@/layout/components/Sidebar/Item';

//已有SPU下的全部品牌数据
let allTradeMarkArr = ref([]);
//获取已有SPU下照片墙的数据
let imgListArr = ref([]);
//获取已有SPU，拥有销售属性
let spuHasSaleAttrArr = ref([]);
//获取全部销售属性[不管任何SPU销售属性最多三个] 颜色  尺码  版本 基础属性
let allSaleAttrArr = ref([]);

// 定义将来添加spu或修改spu需要携带给服务器的参数
let spuParams = ref({})

// 定义收集SPU还没被选择的销售属性ID和名字
let unSaleAttrIdAndName = ref('') 

//照片墙相关的代码
//存储预览图片地址
const dialogImageUrl = ref("");
//控制对话框显示与隐藏
const dialogVisible = ref(false);

//删除图片回调
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles);
};
//预览回调
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

// 定义一个方法方便父组件使用
const initHasSpuData =async (spu)=>{
  spuParams.value = spu
       //在父组件点击修改SPU按钮的时候，触发子组件当前方法，向服务器发四个请求
   //获取全部品牌数据
   let ps1 =  reqAllaTradeMark();
   //获取已有SPU照片墙的数据
   let ps2 = reqImgList(spu.id);
   //获取当前SPU已有销售属性
   let ps3 = reqSpuHasSaleAttr(spu.id);
   //获取全部销售属性
   let ps4 = reqAllSaleAttr();
   //获取全部服务器返回数据
   let result  = await Promise.all([ps1,ps2,ps3,ps4]);
   //存储全部品牌
   allTradeMarkArr.value = result[0];
   //存储照片墙的数据   由于服务器返回的数据格式是imgName , imgUrl
  //  而照片墙需要的是: name url , 所以需要对数据进行处理
   imgListArr.value = result[1].map((item)=>{
         return {
          name: item.imgName,
          url: item.imgUrl
         }
   });
   //存储已有销售属性
   spuHasSaleAttrArr.value = result[2];
   //获取全部销售属性
   allSaleAttrArr.value = result[3];
   

}

// 计算当前SPU,还没有选择的销售属性
const unSelectSaleAttr = computed(()=>{
  // filter回调函数需要返回布尔值 : 真 , 代表过滤出来 ; 假 , 代表新的数组不要
  let result = allSaleAttrArr.value.filter((item)=>{
        return spuHasSaleAttrArr.value.every((item1)=>{
          // 把每一个已有的属性名字跟全部的属性名字做比较, 返回不相等的那个
            return item.name != item1.saleAttrName
        })
  })
   return result
})

// 点击添加销售属性按钮的回调
const addSaleAttr = ()=>{
  // 新增的销售属性 和 ID
  const [baseSaleAttrId,saleAttrName] = unSaleAttrIdAndName.value.split(':')
  // 服务器需要的销售属性对象--新增的销售属性要把属性值列表加上,才是正确格式
  let newSaleAttr = {baseSaleAttrId,saleAttrName,spuSaleAttrValueList: []}
  // 向已有的SPU已有的数组里面追加新增销售属性
  spuHasSaleAttrArr.value.push(newSaleAttr)
  // 添加完毕 ,清空下拉框上显示的数据
  unSaleAttrIdAndName.value = ''
}

// 点击添加属性值的加号按钮的回调
const toEdit = (row)=>{
  // 动态追加flag属性
  row.flag = true
  // 最佳一个属性 : 收集销售属性值 --起始值为空
  row.inputValue = ''

}

// 表单元素input失去焦点的回调
const toLook = (row)=>{
   if(row.inputValue.trim()==''){
     ElMessage({
      type:'error',
      message:'不能为空'
     })
     return
   }

  //  收集属性值与前面已有属性值重复的部分
   let  repeat =  row.spuSaleAttrValueList.find((item)=>{
        return item.saleAttrValueName === row.inputValue
   })

  //  如果重复, 错误信息 ,清空最新收集的同名属性值,显示button
   if(repeat){
    ElMessage({
      type:'error',
      message:'不能重复'
    })
    row.inputValue = ''
    row.flag = false
    return
   }
   row.flag = false
  //  新增属性值
  let newSeleattrVal = {
    baseSaleAttrId:row.baseSaleAttrId,
    saleAttrValueName:row.inputValue
  }
  // 追加到当前销售属性值的数组里面
  row.spuSaleAttrValueList.push(newSeleattrVal)
  // 清空收集属性值数据
  row.inputValue = ''


}

// 点击保存按钮的回调
const save = async ()=>{
  // 整理照片墙的数据
  spuParams.value.spuImageList = imgListArr.value.map((item)=>{
        return {
          imgName : item.name ,
          imgUrl: (item.response && item.response.data) || item.url ,
        };
  });

  // 整理销售属性的参数
  spuParams.value.spuSaleAttrList = spuHasSaleAttrArr.value

  // 发请求
  try {
    await reqAddOrUpdataSpu(spuParams.value)
    ElMessage({
      type:'success',
      message:spuParams.value.id?'修改成功':'添加成功'
    })
    // 触发自定义事件 , 通知父祖家切换场景
    emit('changeScene',{
      scenea:0,
      flag:spuParams.value.id?'update':'add'
    })
  } catch (error) {
    ElMessage({
      type: "error",
      message: spuParams.value.id ? "修改失败" : "添加失败",
    });
    
  }

}

// 点击添加SPU的时候,当前子组件发俩请求(获取所有品牌 , 获取全部销售属性)
const initAddSpu = (c3id:string|number)=>{
    // 添加SPU添加的当前三级分类ID
    spuParams.value.category3Id = c3id
    // 获取全部品牌数据
    let ps1 =  reqAllaTradeMark();
    // 获取全部销售属性
    let ps2 = reqAllSaleAttr();
    let result = await Promise.all([ps1,ps2])
    // 存储全部品牌数据
    allTradeMarkArr.value = result[0];
    // 存储全部销售属性
    allSaleAttrArr.value = result[1];
}

//触发自定义事件
let emit = defineEmits(["changeScene"]);
defineExpose({initHasSpuData,initAddSpu})
</script>

<style scoped></style>
